﻿Imports Abyx.SVCMS.Library.DB
Imports System.Data.SqlClient

Public Class SecManager
    Inherits ManagerBase

#Region "Constructors"
    Public Sub New(ByVal LoggedInUser As UserType)
        MyBase.New(LoggedInUser)
    End Sub
#End Region

#Region "Exposed BL Functions"
#Region "Admin user tasks"
    Public Function Reset_AdminUser() As Boolean

        'Do reset
        Dim UserTypeObject As UserType = Nothing
        Dim dt As DataTable = Nothing
        Using con As New SqlConnection(Utility.GetConnectionString)
            con.Open()
            Dim trans As SqlTransaction = con.BeginTransaction

            'Delete if exists
            UserTypeObject = New UserType(New Guid("4EDCB32E-55E3-49E3-B16D-3AF2335800B0"))
            UserTypeObject.Connection = con
            UserTypeObject.Transaction = trans
            If UserTypeObject.Load() Then
                UserTypeObject.Delete()
            End If

            'Recreate Admin user
            Dim nUser As New UserType(New Guid("4EDCB32E-55E3-49E3-B16D-3AF2335800B0"))
            nUser.UserName = "Admin"
            nUser.UserType = SEC_UserTypesEnum.System
            nUser.PasswordVisible = "admin"
            nUser.AccessLevel = SEC_AccessLevelsEnum.System_Administrator
            nUser.Connection = con
            nUser.Transaction = trans
            nUser.Insert()

            'Fetch all the rights from rights table
            Dim rights As New RightTypeCollection
            rights.Connection = con
            rights.Transaction = trans
            rights.Load("SELECT * FROM [SEC_Rights]")
            For Each r As RightType In rights
                Dim userRight As New UserRightType(Guid.NewGuid)
                With userRight
                    .Connection = con
                    .Transaction = trans
                    .UserId = nUser.UserId
                    .RightsId = r.RightsId
                    .Insert()
                End With
            Next

            trans.Commit()
            con.Close()
        End Using

        Return True
    End Function
    Public Function SetPassword_AdminUser(NewPassword As String) As Boolean

        ''Check authentication
        'If IsMethodAuthorized(System.Reflection.MethodBase.GetCurrentMethod, Me.iLMuser) = False Then
        '    Throw New UnauthorizedAccessException("You are not allowed to perform this action")
        'End If

        Dim UserTypeObject As UserType = Nothing
        Dim dt As DataTable = Nothing
        Using con As New SqlConnection(Utility.GetConnectionString)
            con.Open()
            Dim trans As SqlTransaction = con.BeginTransaction

            'Load admin user
            UserTypeObject = New UserType(New Guid("4EDCB32E-55E3-49E3-B16D-3AF2335800B0"))
            UserTypeObject.Connection = con
            UserTypeObject.Transaction = trans
            If UserTypeObject.Load() Then
                'Save with new password
                UserTypeObject.PasswordVisible = NewPassword
                UserTypeObject.Update()
            End If

            trans.Commit()
            con.Close()
        End Using

        Return True
    End Function
    Public Function Get_AdminUser() As UserType

        Dim UserTypeObject As UserType = Nothing

        'Load admin user
        Dim users As New UserTypeCollection
        Using con As New SqlConnection(Utility.GetConnectionString)
            con.Open()
            UserTypeObject = New UserType(New Guid("4EDCB32E-55E3-49E3-B16D-3AF2335800B0"))
            UserTypeObject.Connection = con
            UserTypeObject.Load()
            con.Close()
        End Using

        'return result
        Return UserTypeObject
    End Function
#End Region
#Region "UserType"
    Public Function Update_UserInfo(userTypeObject As UserType) As Boolean

        If userTypeObject Is Nothing Then
            Return False
        End If

        'Validate data
        If userTypeObject.UserId = Guid.Empty Then
            Throw New DataValidationException("UserId cannot be empty")
        End If
        If userTypeObject.UserName = "" Then
            Throw New DataValidationException("Username field cannot be empty")
        End If
        If userTypeObject.PasswordVisible = "" Then
            Throw New DataValidationException("Password field cannot be empty")
        End If
        If userTypeObject.Department = "" Then
            Throw New DataValidationException("Department field cannot be empty")
        End If
        If Me.Check_UserName_Exists(userTypeObject) Then
            Throw New DataValidationException("User name already exists")
        End If

        'Update db
        Dim cmd As New SqlCommand("SELECT COUNT(*) " & _
                                  "FROM [SEC_Users] WHERE [UserId]='" & userTypeObject.UserId.ToString & "'")
        Using con As New SqlConnection(Utility.GetConnectionString)
            con.Open()
            Dim trans As SqlTransaction = con.BeginTransaction
            cmd.Connection = con
            cmd.Transaction = trans

            'check if Id already exists
            If Utility.GetRecordCount(cmd) > 0 Then
                'Update this existing record
                userTypeObject.Connection = con
                userTypeObject.Transaction = trans
                userTypeObject.Update()
            Else
                'insert new record
                userTypeObject.Connection = con
                userTypeObject.Transaction = trans
                userTypeObject.Insert()
            End If

            trans.Commit()
            con.Close()
        End Using


        Return True
    End Function
    Public Sub Delete_UserInfo(userTypeObject As UserType)

        'Do validation

        'Do deletion
        Using con As New SqlConnection(Utility.GetConnectionString)
            con.Open()
            With userTypeObject
                .Connection = con
                .Delete()
            End With
            con.Close()
        End Using

    End Sub
    Public Function Check_UserName_Exists(UserTypeObject As UserType) As Boolean

        'first check if the id exists
        'if so then check the username against all other id's
        'else check all the usernames
        Dim cmd As New SqlCommand("SELECT COUNT(*) " & _
                                  "FROM [SEC_Users] WHERE [UserId]='" & UserTypeObject.UserId.ToString & "'")

        Dim res As Boolean = False
        Using con As New SqlConnection(Utility.GetConnectionString)
            con.Open()
            cmd.Connection = con
            If Utility.GetRecordCount(cmd) > 0 Then
                cmd.CommandText = "SELECT COUNT(*) " & _
                                  "FROM [SEC_Users] WHERE ([UserName]='" & UserTypeObject.UserName & "') " & _
                                  "     AND ([UserId]<>'" & UserTypeObject.UserId.ToString & "')"
                If Utility.GetRecordCount(cmd) > 0 Then
                    res = True
                Else
                    res = False
                End If
            Else
                cmd.CommandText = "SELECT COUNT(*) " & _
                                  "FROM [SEC_Users] WHERE [UserName]='" & UserTypeObject.UserName & "'"
                If Utility.GetRecordCount(cmd) > 0 Then
                    res = True
                Else
                    res = False
                End If
            End If
            con.Close()
        End Using
        Return res
    End Function
    Public Function Get_UsersInfos_All() As UserTypeCollection

        'fetch user lit
        Dim users As New UserTypeCollection
        Using con As New SqlConnection(Utility.GetConnectionString)
            con.Open()
            users.Connection = con
            users.Load("SELECT * FROM SEC_Users")
            con.Close()
        End Using

        'return results
        Return users
    End Function
    Public Function Get_UserDepartments_All() As ObjectModel.Collection(Of String)
        Dim rt As New ObjectModel.Collection(Of String)

        Using con As New SqlConnection(Utility.GetConnectionString)
            con.Open()
            Dim cmd As New SqlCommand("SELECT DISTINCT [Department] FROM [SEC_Users] WHERE (NOT Department IS NULL)")
            cmd.Connection = con
            rt = Utility.GetUniqueFieldList(cmd)
            con.Close()
        End Using

        Return rt
    End Function
#End Region
#End Region

#Region "Shared Methods"
    'Shared Function IsMethodAuthorized(Method As System.Reflection.MethodBase, LoggedInUser As UserType) As Boolean
    '    Dim methodName As String = Method.DeclaringType.FullName & "." & Method.Name
    '    'Make sure we destroy the reference after use Stack traces take up a lot of memory so be careful
    '    Method = Nothing

    '    Return IsMethodAuthorized(methodName, LoggedInUser)

    'End Function
    'Shared Function IsMethodAuthorized(methodName As String, LoggedInUser As UserType) As Boolean

    '    If LoggedInUser Is Nothing Then
    '        Return False
    '    Else
    '        Select Case methodName
    '            'Security Management Functions
    '            Case Is = "Abyx.SVCMS.Library.SecManager.ResetAdminUser"
    '                Select Case LoggedInUser.AccessLevel
    '                    Case Is = SEC_AccessLevelsEnum.System_Administrator, SEC_AccessLevelsEnum.Manager
    '                        Return True
    '                    Case Else
    '                        Return False
    '                End Select
    '            Case Is = "Abyx.SVCMS.Library.SecManager.SetAdminPassword"
    '                Select Case LoggedInUser.AccessLevel
    '                    Case Is = SEC_AccessLevelsEnum.System_Administrator, SEC_AccessLevelsEnum.Manager
    '                        Return True
    '                    Case Else
    '                        Return False
    '                End Select
    '            Case Is = "Abyx.SVCMS.Library.SecManager.GetUsersList"
    '                Select Case LoggedInUser.AccessLevel
    '                    Case Is = SEC_AccessLevelsEnum.System_Administrator, SEC_AccessLevelsEnum.Manager
    '                        Return True
    '                    Case Else
    '                        Return False
    '                End Select

    '                'Win UI functions
    '                'Panel Contents Viewing Rights
    '            Case Is = "Abyx.SVCMS.WinUI.SVCM_Form.PanelContentsRefreshUsers"
    '                Select Case LoggedInUser.AccessLevel
    '                    Case Is = SEC_AccessLevelsEnum.System_Administrator, SEC_AccessLevelsEnum.Manager
    '                        Return True
    '                    Case Else
    '                        Return False
    '                End Select
    '                'Security Tab BL functions
    '            Case Is = "Abyx.SVCMS.WinUI.SVCM_Form.MNU_Security_AddUser"
    '                Select Case LoggedInUser.AccessLevel
    '                    Case Is = SEC_AccessLevelsEnum.System_Administrator, SEC_AccessLevelsEnum.Manager
    '                        Return True
    '                    Case Else
    '                        Return False
    '                End Select
    '            Case Is = "Abyx.SVCMS.WinUI.SVCM_Form.MNU_Security_AlterUser"
    '                Select Case LoggedInUser.AccessLevel
    '                    Case Is = SEC_AccessLevelsEnum.System_Administrator, SEC_AccessLevelsEnum.Manager
    '                        Return True
    '                    Case Else
    '                        Return False
    '                End Select
    '            Case Is = "Abyx.SVCMS.WinUI.SVCM_Form.MNU_Security_DeleteUser"
    '                Select Case LoggedInUser.AccessLevel
    '                    Case Is = SEC_AccessLevelsEnum.System_Administrator, SEC_AccessLevelsEnum.Manager
    '                        Return True
    '                    Case Else
    '                        Return False
    '                End Select
    '            Case Is = "Abyx.SVCMS.WinUI.SVCM_Form.MNU_Security_ChangePassword"
    '                Select Case LoggedInUser.AccessLevel
    '                    Case Else
    '                        Return True
    '                End Select
    '            Case Is = "Abyx.SVCMS.WinUI.SVCM_Form.MNU_Security_ResetAdminUser"
    '                Select Case LoggedInUser.AccessLevel
    '                    Case Is = SEC_AccessLevelsEnum.System_Administrator, SEC_AccessLevelsEnum.Manager
    '                        Return True
    '                    Case Else
    '                        Return False
    '                End Select
    '            Case Is = "Abyx.SVCMS.WinUI.SVCM_Form.MNU_Security_SetAdminPassword"
    '                Select Case LoggedInUser.AccessLevel
    '                    Case Is = SEC_AccessLevelsEnum.System_Administrator, SEC_AccessLevelsEnum.Manager
    '                        Return True
    '                    Case Else
    '                        Return False
    '                End Select
    '            Case Else
    '                Return False
    '        End Select
    '    End If

    '    'Failsafe incase we forget to insert new branches access to them will not be allowed
    '    Return False
    'End Function
    Shared Function Login(UserName As String, Password As String) As UserType

        Dim UserTypeObject As New UserType

        'Data validation
        If UserName = String.Empty Or Password = String.Empty Then
            Throw New DataValidationException("Invalid username or password")
        End If

        'Query DB
        Dim dt As DataTable = Nothing
        Using con As New SqlConnection(Utility.GetConnectionString)
            con.Open()
            Dim sql As String = "SELECT * " & _
                                "FROM SEC_Users " & _
                                "WHERE UserName = @UserName" & _
                                "  AND Password = @Password"
            Dim cmd As New SqlCommand(sql)
            cmd.Parameters.AddWithValue("@UserName", UserName)
            cmd.Parameters.AddWithValue("@Password", Utility.HashBytes_SHA512(Password))
            cmd.Connection = con
            dt = Utility.GetList(cmd)
            con.Close()
        End Using

        'Check for results
        If IsNothing(dt) Then
            Return Nothing
        End If
        If dt.Rows.Count < 1 Then
            Return Nothing
        End If

        'Return results
        If UserTypeObject.Load(dt.Rows(0)) Then
            Return UserTypeObject
        Else
            Return Nothing
        End If

    End Function
#End Region

End Class
